﻿/*
 Wrap Interface of Kinect2 SDK
 According to MS Kinect SDK Vesrion 2.0.1410.19000

 Date : 2014/12/3
 Version : 0.5
 
The MIT License (MIT)

Copyright (c) 2014 DavidWTF

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;

namespace Kinect2
{
    namespace Face
    {
        using WAITABLE_HANDLE = System.IntPtr;
        using TIMESPAN = System.Int64;
        using HRESULT = System.Int32;
        using DWORD = System.UInt32;

        public class FaceAlignment : BaseInterfaceWrap<IFaceAlignment>
        {
            internal FaceAlignment(IFaceAlignment arg) : base(arg) { }
            public FaceAlignment()
                : base()
            {
                IFaceAlignment faceAlignment;
                KinectFace.CreateFaceAlignment(out faceAlignment);
                if (faceAlignment == null)
                    throw new NullReferenceException();
                origin = faceAlignment;
            }
            public Vector4 FaceOrientation
            {
                get { return GetMember<Vector4>("FaceOrientation"); }
                set { PutMember<Vector4>("FaceOrientation", value); }
            }
            public CameraSpacePoint HeadPivotPoint
            {
                get { return GetMember<CameraSpacePoint>("HeadPivotPoint"); }
                set { PutMember<CameraSpacePoint>("HeadPivotPoint", value); }
            }
            public FaceAlignmentQuality Quality
            {
                get { return GetMember<FaceAlignmentQuality>("Quality"); }
            }
            public IDictionary<FaceShapeAnimations, float> AnimationUnits
            {
                get
                {
                    try
                    {
                        Dictionary<FaceShapeAnimations, float> dict = new Dictionary<FaceShapeAnimations, float>((int)FaceShapeAnimations.Count);
                        float[] animationUnits = new float[(int)FaceShapeAnimations.Count];
                        origin.GetAnimationUnits((uint)animationUnits.Length, animationUnits);
                        for (int i = 0; i < animationUnits.Length; i++)
                            dict[(FaceShapeAnimations)i] = animationUnits[i];
                        return dict;
                    }
                    catch { }
                    return null;
                }
            }
        }

        public class FaceFrame : BaseInterfaceWrap<IFaceFrame>
        {
            public FaceFrame() : base() { }
            internal FaceFrame(IFaceFrame arg) : base(arg) { }
            public BodyFrameReference BodyFrameReference
            {
                get { return GetWrappedClass<BodyFrameReference>("BodyFrameReference"); }
            }
            public ColorFrameReference ColorFrameReference
            {
                get { return GetWrappedClass<ColorFrameReference>("ColorFrameReference"); }
            }
            public DepthFrameReference DepthFrameReference
            {
                get { return GetWrappedClass<DepthFrameReference>("DepthFrameReference"); }
            }
            public InfraredFrameReference InfraredFrameReference
            {
                get { return GetWrappedClass<InfraredFrameReference>("InfraredFrameReference"); }
            }
            public bool IsTrackingIdValid
            {
                get { return GetMember<bool>("IsTrackingIdValid"); }
            }
            public TimeSpan RelativeTime
            {
                get { return GetTimeSpan("RelativeTime"); }
            }
            public FaceFrameResult FaceFrameResult
            {
                get { return GetWrappedClass<FaceFrameResult>("FaceFrameResult"); }
            }
            public FaceFrameSource FaceFrameSource
            {
                get { return GetWrappedClass<FaceFrameSource>("FaceFrameSource"); }
            }
        }

        public class FaceFrameResult : BaseInterfaceWrap<IFaceFrameResult>
        {
            public FaceFrameResult() : base() { }
            internal FaceFrameResult(IFaceFrameResult arg) : base(arg) { }
            public RectI FaceBoundingBoxInColorSpace
            {
                get { return GetMember<RectI>("FaceBoundingBoxInColorSpace"); }
            }
            public RectI FaceBoundingBoxInInfraredSpace
            {
                get { return GetMember<RectI>("FaceBoundingBoxInInfraredSpace"); }
            }
            public FaceFrameFeatures FaceFrameFeatures
            {
                get { return (FaceFrameFeatures)GetMember<DWORD>("FaceFrameFeatures"); }
            }
            public IDictionary<FacePointType, PointF> FacePointsInColorSpace
            {
                get
                {
                    try
                    {
                        Dictionary<FacePointType, PointF> dict = new Dictionary<FacePointType, PointF>((int)FacePointType.Count);
                        PointF[] facePoints = new PointF[(int)FacePointType.Count];
                        origin.GetFacePointsInColorSpace((uint)facePoints.Length, facePoints);
                        for (int i = 0; i < facePoints.Length; i++)
                            dict[(FacePointType)i] = facePoints[i];
                        return dict;
                    }
                    catch { }
                    return null;
                }
            }
            public IDictionary<FacePointType, PointF> FacePointsInInfraredSpace
            {
                get
                {
                    try
                    {
                        Dictionary<FacePointType, PointF> dict = new Dictionary<FacePointType, PointF>((int)FacePointType.Count);
                        PointF[] facePoints = new PointF[(int)FacePointType.Count];
                        origin.GetFacePointsInInfraredSpace((uint)facePoints.Length, facePoints);
                        for (int i = 0; i < facePoints.Length; i++)
                            dict[(FacePointType)i] = facePoints[i];
                        return dict;
                    }
                    catch { }
                    return null;
                }
            }
            public IDictionary<FaceProperty, DetectionResult> FaceProperties
            {
                get
                {
                    try
                    {
                        Dictionary<FaceProperty, DetectionResult> dict = new Dictionary<FaceProperty, DetectionResult>((int)FaceProperty.Count);
                        DetectionResult[] detectionResults = new DetectionResult[(int)FaceProperty.Count];
                        origin.GetFaceProperties((uint)detectionResults.Length, detectionResults);
                        for (int i = 0; i < detectionResults.Length; i++)
                            dict[(FaceProperty)i] = detectionResults[i];
                        return dict;
                    }
                    catch { }
                    return null;
                }
            }
            public Vector4 FaceRotationQuaternion
            {
                get { return GetMember<Vector4>("FaceRotationQuaternion"); }
            }
            public TimeSpan RelativeTime
            {
                get { return GetTimeSpan("RelativeTime"); }
            }
            public ulong TrackingId
            {
                get { return GetMember<ulong>("TrackingId"); }
            }
        }

        public class TrackingIdLostEventArgs : BaseEventArgs<ITrackingIdLostEventArgs>
        {
            public TrackingIdLostEventArgs() : base() { }
            internal TrackingIdLostEventArgs(ITrackingIdLostEventArgs arg) : base(arg) { }
            public ulong TrackingId
            {
                get
                {
                    try { return origin.get_TrackingId(); }
                    catch { }
                    return 0;
                }
            }
        }

        public class FaceFrameSource : FrameSourceWidthEvent<IFaceFrameSource, FaceFrameReader, TrackingIdLostEventArgs>
        {
            public FaceFrameSource() : base("SubscribeTrackingIdLost", "UnsubscribeTrackingIdLost", "GetTrackingIdLostEventData") { }
            internal FaceFrameSource(IFaceFrameSource arg) : base(arg, "SubscribeTrackingIdLost", "UnsubscribeTrackingIdLost", "GetTrackingIdLostEventData") { }
            public FaceFrameSource(KinectSensor sensor, ulong initialTrackingId, FaceFrameFeatures initialFaceFrameFeatures)
                : base("SubscribeTrackingIdLost", "UnsubscribeTrackingIdLost", "GetTrackingIdLostEventData")
            {
                IFaceFrameSource source = null;
                KinectFace.CreateFaceFrameSource((IKinectSensor)sensor.Origin, initialTrackingId, (uint)initialFaceFrameFeatures, out source);
                if (source == null)
                    throw new NullReferenceException("IFaceFrameSource");
                origin = source;
            }
            //public Microsoft.Kinect.MultiSourceFrame CurrentFrame { get; }
            public FaceFrameFeatures FaceFrameFeatures
            {
                get { return (FaceFrameFeatures)GetMember<DWORD>("FaceFrameFeatures"); }
                set { PutMember<DWORD>("FaceFrameFeatures", (DWORD)value); }
            }
            public bool IsTrackingIdValid
            {
                get { return GetMember<bool>("IsTrackingIdValid"); }
            }
            public ulong TrackingId
            {
                get { return GetMember<ulong>("TrackingId"); }
                set { PutMember<ulong>("TrackingId", value); }
            }
            public event EventHandler<TrackingIdLostEventArgs> TrackingIdLost
            {
                add { Add_EventHandler(value); }
                remove { Remove_EventHandler(value); }
            }
        }

        public class FaceFrameReference : FrameReference<IFaceFrameReference, FaceFrame>
        {
            public FaceFrameReference() : base() { }
            internal FaceFrameReference(IFaceFrameReference arg) : base(arg) { }
        }

        public class FaceFrameArrivedEventArgs : FrameArrivedEventArgs<IFaceFrameArrivedEventArgs, FaceFrameReference>
        {
            public FaceFrameArrivedEventArgs() : base() { }
            internal FaceFrameArrivedEventArgs(IFaceFrameArrivedEventArgs arg) : base(arg) { }
        }

        public class FaceFrameReader : FrameReaderWithAcquire<IFaceFrameReader, FaceFrame, FaceFrameArrivedEventArgs>
        {
            public FaceFrameReader() : base() { }
            internal FaceFrameReader(IFaceFrameReader arg) : base(arg) { }
            public FaceFrameSource FaceFrameSource
            {
                get { return GetWrappedClass<FaceFrameSource>("FaceFrameSource"); }
            }
        }

        public class FaceModel : BaseInterfaceWrap<IFaceModel>
        {
            internal FaceModel(IFaceModel arg) : base(arg) { }
            public FaceModel()
                : base()
            {
                IFaceModel model = null;
                float[] deformations = new float[(int)Kinect2.Face.FaceShapeDeformations.Count];
                for (int i = 0; i < deformations.Length; i++)
                    deformations[i] = 0;
                KinectFace.CreateFaceModel(1.0f, (uint)deformations.Length, deformations, out model);
                if (model == null)
                    throw new NullReferenceException();
                origin = model;
            }
            public FaceModel(float scale, IDictionary<FaceShapeDeformations, float> faceShapeDeformations)
            {
                IFaceModel model = null;
                float[] deformations = new float[faceShapeDeformations.Count];
                for (int i = 0; i < faceShapeDeformations.Count; i++)
                    deformations[i] = faceShapeDeformations[(FaceShapeDeformations)i];
                KinectFace.CreateFaceModel(scale, (uint)deformations.Length, deformations, out model);
                if (model == null)
                    throw new NullReferenceException();
                origin = model;
            }
            public IList<CameraSpacePoint> CalculateVerticesForAlignment(FaceAlignment faceAlignment)
            {
                try
                {
                    int count = (int)VertexCount;
                    CameraSpacePoint[] vertices = new CameraSpacePoint[count];
                    origin.CalculateVerticesForAlignment((IFaceAlignment)faceAlignment.Origin, VertexCount, vertices);
                    return vertices;
                }
                catch { }
                return null;
            }
            public IDictionary<FaceShapeDeformations, float> FaceShapeDeformations
            {
                get
                {
                    try
                    {
                        Dictionary<FaceShapeDeformations, float> dict = new Dictionary<FaceShapeDeformations, float>((int)FaceShapeDeformations.Count);
                        float[] deformations = new float[(int)FaceShapeDeformations.Count];
                        origin.GetFaceShapeDeformations((uint)deformations.Length, deformations);
                        for (int i = 0; i < deformations.Length; i++)
                            dict[(FaceShapeDeformations)i] = deformations[i];
                        return dict;
                    }
                    catch { }
                    return null;
                }
            }
            public uint HairColor
            {
                get { return GetMember<uint>("HairColor"); }
            }
            public uint SkinColor
            {
                get { return GetMember<uint>("SkinColor"); }
            }
            public float Scale
            {
                get { return GetMember<float>("Scale"); }
            }
            public uint TriangleCount
            {
                get
                {
                    try
                    {
                        UInt32 triangleCount = 0;
                        KinectFace.GetFaceModelTriangleCount(out triangleCount);
                        return triangleCount;
                    }
                    catch { }
                    return 0;
                }
            }
            public uint VertexCount
            {
                get
                {
                    try
                    {
                        UInt32 vertexCount = 0;
                        KinectFace.GetFaceModelVertexCount(out vertexCount);
                        return vertexCount;
                    }
                    catch { }
                    return 0;
                }
            }
            public IList<uint> TriangleIndices
            {
                get
                {
                    try
                    {
                        uint[] triangeVertices = new uint[(int)TriangleCount * 3];
                        KinectFace.GetFaceModelTriangles((uint)triangeVertices.Length, triangeVertices);
                        return triangeVertices;
                    }
                    catch { }
                    return null;
                }
            }
        }

        public class FaceModelBuilderCaptureStatusChangedEventArgs : BaseEventArgs<ICaptureStatusChangedEventArgs>
        {
            public FaceModelBuilderCaptureStatusChangedEventArgs() : base() { }
            internal FaceModelBuilderCaptureStatusChangedEventArgs(ICaptureStatusChangedEventArgs arg) : base(arg) {}
            public FaceModelBuilderCaptureStatus PreviousCaptureStatus 
            {
                get { return origin.get_PreviousCaptureStatus(); }
            }
        }

        public class FaceModelBuilderCollectionStatusChangedEventArgs : BaseEventArgs<ICollectionStatusChangedEventArgs>
        {
            public FaceModelBuilderCollectionStatusChangedEventArgs() : base() { }
            internal FaceModelBuilderCollectionStatusChangedEventArgs(ICollectionStatusChangedEventArgs arg) : base(arg) {}
            public FaceModelBuilderCollectionStatus PreviousCollectionStatus
            {
                get { return origin.get_PreviousCollectionStatus(); }
            }
        }

        public class FaceModelBuilderCollectionCompletedEventArgs : EventArgs, IOrigin
        {
            IFaceModelBuilder origin;
            Type originType = typeof(IFaceModelBuilder);
            public FaceModelBuilderCollectionCompletedEventArgs() : base() { }
            internal FaceModelBuilderCollectionCompletedEventArgs(IFaceModelBuilder arg) : base()
            {
                if (arg == null)
                    throw new NullReferenceException();
                origin = arg;
            }
            public object Origin
            {
                get { return origin; }
                set { origin = (IFaceModelBuilder) value; }
            }
            public Type OriginType
            {
                get { return originType; }
                set { originType = value; }
            }
            public FaceModelData ModelData 
            {
                get 
                {
                    try { return new FaceModelData(origin.GetFaceData()); }
                    catch { }
                    return null;
                }
            }
        }

        public class FaceModelBuilder : BaseInterfaceWrap<IFaceModelBuilder>
        {
            public FaceModelBuilder() : base() 
            {
                eventCaptureStatusChanged = new Event_CaptureStatusChanged();
                eventCollectionStatusChanged = new Event_CollectionStatusChanged();

            }
            internal FaceModelBuilder(IFaceModelBuilder arg) : base(arg) 
            {
                eventCaptureStatusChanged = new Event_CaptureStatusChanged(arg);
                eventCollectionStatusChanged = new Event_CollectionStatusChanged(arg);
            }
            public void BeginFaceDataCollection()
            {
                try { origin.BeginFaceDataCollection(); }
                catch { }
            }
            public FaceModelBuilderCaptureStatus CaptureStatus
            {
                get { return GetMember<FaceModelBuilderCaptureStatus>("CaptureStatus"); }
            }
            public FaceModelBuilderCollectionStatus CollectionStatus
            {
                get { return GetMember<FaceModelBuilderCollectionStatus>("CollectionStatus"); }
            }
            public FaceModelData GetFaceData()
            {
                try { return new FaceModelData(origin.GetFaceData()); }
                catch { }
                return null;
            }
            public override object Origin
            {
                get { return origin; }
                set 
                {
                    origin = (IFaceModelBuilder)value; 
                    eventCaptureStatusChanged.Origin = origin;
                    eventCollectionStatusChanged.Origin = origin;
                }
            }
            public override void Dispose() 
            {
                base.Dispose();
                eventCaptureStatusChanged.Dispose();
                eventCollectionStatusChanged.Dispose();
            }
            class Event_CaptureStatusChanged : BaseEvent<IFaceModelBuilder, FaceModelBuilderCaptureStatusChangedEventArgs>
            {
                public Event_CaptureStatusChanged() : base("SubscribeCaptureStatusChanged", "UnsubscribeCaptureStatusChanged", "GetCaptureStatusChangedEventData") { }
                public Event_CaptureStatusChanged(IFaceModelBuilder arg) : base(arg, "SubscribeCaptureStatusChanged", "UnsubscribeCaptureStatusChanged", "GetCaptureStatusChangedEventData") { }
                public void AddEventHandler(EventHandler<FaceModelBuilderCaptureStatusChangedEventArgs> v)
                {
                    Add_EventHandler(v);
                }
                public void RemoveEventHandler(EventHandler<FaceModelBuilderCaptureStatusChangedEventArgs> v)
                {
                    Remove_EventHandler(v);
                }
                public override void Dispose() 
                {
                    origin = null;
                    RemoveAll_EventHandler();
                }
            }
            Event_CaptureStatusChanged eventCaptureStatusChanged;
            public event EventHandler<FaceModelBuilderCaptureStatusChangedEventArgs> CaptureStatusChanged
            {
                add { eventCaptureStatusChanged.AddEventHandler(value); }
                remove { eventCaptureStatusChanged.RemoveEventHandler(value); }
            }

            class Event_CollectionStatusChanged : BaseEvent<IFaceModelBuilder, FaceModelBuilderCollectionStatusChangedEventArgs>
            {
                public Event_CollectionStatusChanged() : base("SubscribeCollectionStatusChanged", "UnsubscribeCollectionStatusChanged", "GetCollectionStatusChangedEventData") { }
				public Event_CollectionStatusChanged(IFaceModelBuilder arg) : base(arg, "SubscribeCollectionStatusChanged", "UnsubscribeCollectionStatusChanged", "GetCollectionStatusChangedEventData") { }
				
				EventHandler<FaceModelBuilderCollectionCompletedEventArgs> eventHandler2;

                public void AddEventHandler(EventHandler<FaceModelBuilderCollectionStatusChangedEventArgs> v)
                {
                    Add_EventHandler(v);
                }
                public void AddEventHandler2(EventHandler<FaceModelBuilderCollectionCompletedEventArgs> v)
                {
                    if (handle == IntPtr.Zero)
                    {
                        try
                        {
                            handle = origin.SubscribeCollectionStatusChanged();
                            EventRouter.AddWaitableHandle(handle, this);
                        }
                        catch { }
                    }
                    eventHandler2 = (EventHandler<FaceModelBuilderCollectionCompletedEventArgs>)(object)System.Delegate.Combine(eventHandler2, v);
                }
                public void RemoveEventHandler(EventHandler<FaceModelBuilderCollectionStatusChangedEventArgs> v)
                {
                    eventHandler = (EventHandler<FaceModelBuilderCollectionStatusChangedEventArgs>)System.Delegate.Remove(eventHandler, v);
                    if (eventHandler == null && eventHandler2 == null && handle != IntPtr.Zero)
                    {
                        try
                        {
                            EventRouter.RemoveWaitableHandle(handle);
                            origin.UnsubscribeCollectionStatusChanged(handle);
                        }
                        catch { }
                        handle = IntPtr.Zero;
                    }
                }
                public void RemoveEventHandler2(EventHandler<FaceModelBuilderCollectionCompletedEventArgs> v)
                {
                    eventHandler2 = (EventHandler<FaceModelBuilderCollectionCompletedEventArgs>)System.Delegate.Remove(eventHandler, v);
                    if (eventHandler == null && eventHandler2 == null && handle != IntPtr.Zero)
                    {
                        try
                        {
                            EventRouter.RemoveWaitableHandle(handle);
                            origin.UnsubscribeCollectionStatusChanged(handle);
                        }
                        catch { }
                        handle = IntPtr.Zero;
                    }
                }
                public override void Raise(WAITABLE_HANDLE handle)
                {
                    try
                    {
                        using (FaceModelBuilderCollectionStatusChangedEventArgs e = new FaceModelBuilderCollectionStatusChangedEventArgs())
                        {
                            e.Origin = origin.GetCollectionStatusChangedEventData(handle);

                            if (eventHandler != null)
                                eventHandler(this, e);

                            if (e.PreviousCollectionStatus == FaceModelBuilderCollectionStatus.Complete && eventHandler2 != null)
                                eventHandler2(this, new FaceModelBuilderCollectionCompletedEventArgs(origin));

                        }
                    }
                    catch { }
                }
                protected override void RemoveAll_EventHandler()
                {
                    base.RemoveAll_EventHandler();
                    eventHandler2 = null;
                }
                public override void Dispose()
                {
                    origin = null;
                    RemoveAll_EventHandler();
                }
            }
            Event_CollectionStatusChanged eventCollectionStatusChanged;
            public event EventHandler<FaceModelBuilderCollectionStatusChangedEventArgs> CollectionStatusChanged
            {
                add { eventCollectionStatusChanged.AddEventHandler(value); }
                remove { eventCollectionStatusChanged.RemoveEventHandler(value); }
            }
            public event EventHandler<FaceModelBuilderCollectionCompletedEventArgs> CollectionCompleted
            {
                add { eventCollectionStatusChanged.AddEventHandler2(value); }
                remove { eventCollectionStatusChanged.RemoveEventHandler2(value); }
            }
        }

        public class FaceModelData : BaseInterfaceWrap<IFaceModelData>
        {
            public FaceModelData() : base() { }
            internal FaceModelData(IFaceModelData arg) : base(arg) { }
            public FaceModel ProduceFaceModel()
            {
                try { return new FaceModel(origin.ProduceFaceModel()); }
                catch { }
                return null;
            }
        }

        public class HighDefinitionFaceFrame : BaseInterfaceWrap<IHighDefinitionFaceFrame>
        {
            public HighDefinitionFaceFrame() : base() { }
            internal HighDefinitionFaceFrame(IHighDefinitionFaceFrame arg) : base(arg) { }
            public void GetAndRefreshFaceAlignmentResult(FaceAlignment faceAlignment)
            {
                try { origin.GetAndRefreshFaceAlignmentResult((IFaceAlignment)faceAlignment.Origin); }
                catch { }
            }
            public BodyFrameReference BodyFrameReference
            {
                get { return GetWrappedClass<BodyFrameReference>("BodyFrameReference"); }
            }
            public ColorFrameReference ColorFrameReference
            {
                get { return GetWrappedClass<ColorFrameReference>("ColorFrameReference"); }
            }
            public DepthFrameReference DepthFrameReference
            {
                get { return GetWrappedClass<DepthFrameReference>("DepthFrameReference"); }
            }
            public InfraredFrameReference InfraredFrameReference
            {
                get { return GetWrappedClass<InfraredFrameReference>("InfraredFrameReference"); }
            }
            public FaceAlignmentQuality FaceAlignmentQuality
            {
                get { return GetMember<FaceAlignmentQuality>("FaceAlignmentQuality"); }
            }
            public FaceModel FaceModel
            {
                get { return GetWrappedClass<FaceModel>("FaceModel"); }
            }
            public HighDefinitionFaceFrameSource HighDefinitionFaceFrameSource
            {
                get { return GetWrappedClass<HighDefinitionFaceFrameSource>("HighDefinitionFaceFrameSource"); }
            }
            public bool IsTrackingIdValid
            {
                get { return GetMember<bool>("IsTrackingIdValid"); }
            }
            public bool IsFaceTracked
            {
                get { return GetMember<bool>("IsFaceTracked"); }
            }
            public TimeSpan RelativeTime
            {
                get { return GetTimeSpan("RelativeTime"); }
            }
            public ulong TrackingId
            {
                get { return GetMember<ulong>("TrackingId"); }
            }
        }

        public class HighDefinitionFaceFrameSource : FrameSourceWidthEvent<IHighDefinitionFaceFrameSource, HighDefinitionFaceFrameReader, TrackingIdLostEventArgs>
        {
            public HighDefinitionFaceFrameSource() : base("SubscribeTrackingIdLost", "UnsubscribeTrackingIdLost", "GetTrackingIdLostEventData") { }
            internal HighDefinitionFaceFrameSource(IHighDefinitionFaceFrameSource arg) : base(arg, "SubscribeTrackingIdLost", "UnsubscribeTrackingIdLost", "GetTrackingIdLostEventData") { }
            public HighDefinitionFaceFrameSource(KinectSensor sensor) : base("SubscribeTrackingIdLost", "UnsubscribeTrackingIdLost", "GetTrackingIdLostEventData")
            {
                IHighDefinitionFaceFrameSource source = null;
                KinectFace.CreateHighDefinitionFaceFrameSource((IKinectSensor)sensor.Origin, out source);
                if (source == null)
                    throw new NullReferenceException("IHighDefinitionFaceFrameSource");
                origin = source;
            }
            public FaceModelBuilder OpenModelBuilder(FaceModelBuilderAttributes enabledAttributes)
            {
                try { return new FaceModelBuilder(origin.OpenModelBuilder(enabledAttributes)); }
                catch { }
                return null;
            }
            public void FeedAndCalculateFrameData(Body body, KinectBuffer infraredFrameBuffer, KinectBuffer colorFrameBuffer, KinectBuffer depthFrameBuffer)
            {
                try
                {
                    origin.FeedAndCalculateFrameData((IBody)body.Origin,
                        infraredFrameBuffer.Size / 2, infraredFrameBuffer.UnderlyingBuffer,
                        colorFrameBuffer.Size, colorFrameBuffer.UnderlyingBuffer,
                        depthFrameBuffer.Size, depthFrameBuffer.UnderlyingBuffer);
                }
                catch { }
            }
            public FaceModel FaceModel
            {
                get { return GetWrappedClass<FaceModel>("FaceModel"); }
            }
            public bool IsOnline
            {
                get { return GetMember<bool>("IsOnline"); }
            }
            public bool IsTrackingIdValid
            {
                get { return GetMember<bool>("IsTrackingIdValid"); }
            }
            public FaceAlignmentQuality TrackingQuality
            {
                get { return GetMember<FaceAlignmentQuality>("TrackingQuality"); }
            }
            public ulong TrackingId
            {
                get { return GetMember<ulong>("TrackingId"); }
                set { PutMember<ulong>("TrackingId", value); }
            }
            public event EventHandler<TrackingIdLostEventArgs> TrackingIdLost
            {
                add { Add_EventHandler(value); }
                remove { Remove_EventHandler(value); }
            }
        }

        public class HighDefinitionFaceFrameReference : FrameReference<IHighDefinitionFaceFrameReference, HighDefinitionFaceFrame>
        {
            public HighDefinitionFaceFrameReference() : base() { }
            internal HighDefinitionFaceFrameReference(IHighDefinitionFaceFrameReference arg) : base(arg) { }
        }

        public class HighDefinitionFaceFrameArrivedEventArgs : FrameArrivedEventArgs<IHighDefinitionFaceFrameArrivedEventArgs, HighDefinitionFaceFrameReference>
        {
            public HighDefinitionFaceFrameArrivedEventArgs() : base() { }
            internal HighDefinitionFaceFrameArrivedEventArgs(IHighDefinitionFaceFrameArrivedEventArgs arg) : base(arg) { }
        }

        public class HighDefinitionFaceFrameReader : FrameReaderWithAcquire<IHighDefinitionFaceFrameReader, HighDefinitionFaceFrame, HighDefinitionFaceFrameArrivedEventArgs>
        {
            public HighDefinitionFaceFrameReader() : base() { }
            internal HighDefinitionFaceFrameReader(IHighDefinitionFaceFrameReader arg) : base(arg) { }
            public HighDefinitionFaceFrameSource FaceFrameSource
            {
                get { return GetWrappedClass<HighDefinitionFaceFrameSource>("HighDefinitionFaceFrameSource"); }
            }
        }

    }
}
